﻿using System;
using System.Data.SqlServerCe;
using System.IO;
using System.Linq;
using System.Net.Mime;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using eWallet.Data.Local;
using eWallet.Security.Cryptography;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using eWallet.Collections.Generic;

namespace eWallet.Tests
{
	/// <summary>
	/// Tests that work with data in the typed data set.
	/// </summary>
	[TestClass]
	public class DataTests
	{

		#region Test: public void AddGroup01()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void AddGroup01()
		{
			using (eWalletDataSet ds = new eWalletDataSet())
			{
				ds.Blobs.AddBlobsRow(Guid.NewGuid(), new byte[1]);
				var row = ds.Groups.AddGroupsRow("Key 1", "Description 1", new PasswordCryptoModule("1234"));
				Assert.IsNotNull(row);
				Assert.AreEqual<int>(1, ds.Groups.Count);
				Assert.AreEqual<string>("Key 1", ds.Groups[0].Name);
				Assert.AreEqual<string>("Description 1", ds.Groups[0].Description);
				Assert.AreEqual<EncryptionMethod>(EncryptionMethod.Password, ds.Groups[0].EncryptionMethod);
				Assert.IsNotNull(ds.Groups[0].BlobsRow);
				Assert.IsNotNull(ds.Groups[0].BlobsRow.Data);
				Assert.AreNotEqual<int>(0, ds.Groups[0].BlobsRow.Data.Length);
			}
		}

		#endregion

		#region Test: public void AddGroup02()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void AddGroup02()
		{
			using (eWalletDataSet ds = new eWalletDataSet())
			{
				var row = ds.Groups.AddGroupsRow("Key 1", "Description 1", new CertificationCryptoModule(new X509Certificate2(Properties.Resources.eWalletTestCertificate2)));
				Assert.IsNotNull(row);
				Assert.AreEqual<int>(1, ds.Groups.Count);
				Assert.AreEqual<string>("Key 1", ds.Groups[0].Name);
				Assert.AreEqual<string>("Description 1", ds.Groups[0].Description);
				Assert.AreEqual<EncryptionMethod>(EncryptionMethod.Certificate, ds.Groups[0].EncryptionMethod);
				Assert.IsNotNull(ds.Groups[0].BlobsRow);
				Assert.IsNotNull(ds.Groups[0].BlobsRow.Data);
				Assert.AreNotEqual<int>(0, ds.Groups[0].BlobsRow.Data.Length);
			}
		}

		#endregion



		#region Test: public void CheckSecret01()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute("Checks that the IsTaggedWith method works properly.")]
		public void CheckSecret01()
		{
			using (eWalletDataSet ds = new eWalletDataSet())
			{
				ds.Blobs.AddBlobsRow(Guid.NewGuid(), new byte[0]);
				ds.Groups.AddGroupsRow(Guid.NewGuid(), DateTime.UtcNow, "Admin", "Default", null, EncryptionMethod.Password, ds.Blobs[0], null);

				ds.Secrets.AddSecretsRow("Secret 1", ds.Groups[0], ds.Blobs[0]);
				ds.Secrets.AddSecretsRow("Secret 2", ds.Groups[0], ds.Blobs[0]);

				ds.Tags.AddTagsRow("Tag 1");
				ds.Tags.AddTagsRow("Tag 2");
				ds.Tags.AddTagsRow("Tag 3");

				ds.SecretsTags.AddSecretsTagsRow(ds.Secrets[0], ds.Tags[0]);
				ds.SecretsTags.AddSecretsTagsRow(ds.Secrets[0], ds.Tags[1]);
				ds.SecretsTags.AddSecretsTagsRow(ds.Secrets[1], ds.Tags[1]);
				ds.SecretsTags.AddSecretsTagsRow(ds.Secrets[1], ds.Tags[2]);

				Assert.IsTrue(ds.Secrets[0].IsTaggedWith("Tag 1"));
				Assert.IsTrue(ds.Secrets[0].IsTaggedWith("Tag 2"));
				Assert.IsFalse(ds.Secrets[0].IsTaggedWith("Tag 3"));

				Assert.IsFalse(ds.Secrets[1].IsTaggedWith("Tag 1"));
				Assert.IsTrue(ds.Secrets[1].IsTaggedWith("Tag 2"));
				Assert.IsTrue(ds.Secrets[1].IsTaggedWith("Tag 3"));


				Assert.IsTrue(ds.Secrets[0].IsTaggedWith(ds.Tags.Select(new EventfulList<string>("Tag 1"))));
				Assert.IsTrue(ds.Secrets[0].IsTaggedWith(ds.Tags.Select(new EventfulList<string>("Tag 2"))));
				Assert.IsTrue(ds.Secrets[0].IsTaggedWith(ds.Tags.Select(new EventfulList<string>("Tag 1", "Tag 2"))));
				Assert.IsFalse(ds.Secrets[0].IsTaggedWith(ds.Tags.Select(new EventfulList<string>("Tag 1", "Tag 3"))));

				Assert.IsTrue(ds.Secrets[1].IsTaggedWith(ds.Tags.Select(new EventfulList<string>("Tag 2"))));
				Assert.IsTrue(ds.Secrets[1].IsTaggedWith(ds.Tags.Select(new EventfulList<string>("Tag 3"))));
				Assert.IsTrue(ds.Secrets[1].IsTaggedWith(ds.Tags.Select(new EventfulList<string>("Tag 2", "Tag 3"))));
				Assert.IsFalse(ds.Secrets[1].IsTaggedWith(ds.Tags.Select(new EventfulList<string>("Tag 1", "Tag 3"))));
			}
		}

		#endregion
		


		#region Test: public void CreateEmptyDatabase01()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void CreateEmptyDatabase01()
		{
			string path = string.Format(@"{0}\{1}.sdf", Environment.GetEnvironmentVariable("TEMP"), Guid.NewGuid());
			eWalletDataSet.CreateEmptyDatabase(path);

			Assert.IsTrue(File.Exists(path));
			File.Delete(path);
		}

		#endregion

		#region Test: public void CreateEmptyDatabase02()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void CreateEmptyDatabase02()
		{

			string path = string.Format(@"{0}\{1}.sdf", Environment.GetEnvironmentVariable("TEMP"), Guid.NewGuid());
			eWalletDataSet.CreateEmptyDatabase(path);

			try
			{
				using (SqlCeConnection conn = new SqlCeConnection(string.Format("Data Source={0}", path)))
				{
					conn.Open();
				}
			}
			finally
			{
				if (File.Exists(path))
					File.Delete(path);
			}
		}

		#endregion



		#region Test: public void DecryptGroupKey01()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void DecryptGroupKey01()
		{
			string pwd = "lkjladsflkj";
			using (eWalletDataSet ds = new eWalletDataSet())
			{
				var row = ds.Groups.AddGroupsRow("Name", null, new PasswordCryptoModule(pwd));
				var alg = new PasswordCryptoModule(pwd).Decrypt<SymmetricAlgorithm>(row.BlobsRow.Data, CryptoModule.SymmetricAlgorithmOutputConverter);

				Assert.IsNotNull(alg);
				var encryptor = alg.CreateEncryptor();
				Assert.IsNotNull(encryptor);
			}
		}

		#endregion

		#region Test: public void DecryptGroupKey02()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void DecryptGroupKey02()
		{
			X509Certificate2 cert = new X509Certificate2(Properties.Resources.eWalletTestCertificate1);

			using (eWalletDataSet ds = new eWalletDataSet())
			{
				var row = ds.Groups.AddGroupsRow("Name", null, new CertificationCryptoModule(cert));
				var alg = new CertificationCryptoModule(cert).Decrypt<SymmetricAlgorithm>(row.BlobsRow.Data, CryptoModule.SymmetricAlgorithmOutputConverter);

				Assert.IsNotNull(alg);
				var encryptor = alg.CreateEncryptor();
				Assert.IsNotNull(encryptor);
			}
		}

		#endregion

		#region Test: public void DecryptGroupKey03()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		[ExpectedException(typeof(CryptographicException))]
		public void DecryptGroupKey03()
		{
			string pwd = "lkjladsflkj";
			using (eWalletDataSet ds = new eWalletDataSet())
			{
				var cert = new X509Certificate2(Properties.Resources.eWalletTestCertificate1);
				var row = ds.Groups.AddGroupsRow("Name", null, new PasswordCryptoModule(pwd));
				var alg = new CertificationCryptoModule(cert).Decrypt<SymmetricAlgorithm>(row.EncryptedKey, CryptoModule.SymmetricAlgorithmOutputConverter);
			}
		}

		#endregion

		#region Test: public void DecryptGroupKey04()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		[ExpectedException(typeof(CryptographicException))]
		public void DecryptGroupKey04()
		{
			X509Certificate2 cert = new X509Certificate2(Properties.Resources.eWalletTestCertificate1);

			using (eWalletDataSet ds = new eWalletDataSet())
			{
				var row = ds.Groups.AddGroupsRow("Name", null, new CertificationCryptoModule(cert));
				var alg = new PasswordCryptoModule("password").Decrypt<SymmetricAlgorithm>(row.EncryptedKey, CryptoModule.SymmetricAlgorithmOutputConverter);

				Assert.IsNotNull(alg);
				var encryptor = alg.CreateEncryptor();
				Assert.IsNotNull(encryptor);
			}
		}

		#endregion



		#region Test: public void DecryptSecret01()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void DecryptSecret01()
		{
			string data1 = "lkasjdfl kalkj32 l4k5jl34 lkj34lkj34lkj32e5 lk lkewj5 lkewjtlk welkjlkj lkj llkjlkj";
			string pwd = "lkjlkj45lkj35";
			PasswordCryptoModule module = new PasswordCryptoModule(pwd);
			byte[] cipher = null;
			SymmetricAlgorithm alg = null;

			using (eWalletDataSet ds = new eWalletDataSet())
			{
				var key = ds.Groups.AddGroupsRow("Default", null, module);
				var secret = ds.Secrets.AddSecretsRow(null, data1, key, module);
				cipher = secret.EncryptedSecret;
				alg = module.Decrypt<SymmetricAlgorithm>(key.EncryptedKey, CryptoModule.SymmetricAlgorithmOutputConverter);
			}

			string data2 = new SymmetricKeyCryptoModule(alg).Decrypt<string>(cipher, CryptoModule.StringOutputConverter);
			Assert.AreEqual<string>(data1, data2);
		}

		#endregion

		#region Test: public void DecryptSecret02()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void DecryptSecret02()
		{
			string data1 = "lkasjdfl kalkj32 l4k5jl34 lkj34lkj34lkj32e5 lk lkewj5 lkewjtlk welkjlkj lkj llkjlkj";
			X509Certificate2 cert = new X509Certificate2(Properties.Resources.eWalletTestCertificate2);
			CertificationCryptoModule module = new CertificationCryptoModule(cert);
			byte[] cipher = null;
			SymmetricAlgorithm alg = null;

			using (eWalletDataSet ds = new eWalletDataSet())
			{
				var key = ds.Groups.AddGroupsRow("Default", null, module);
				var secret = ds.Secrets.AddSecretsRow(null, data1, key, module);
				cipher = secret.EncryptedSecret;
				alg = module.Decrypt<SymmetricAlgorithm>(key.EncryptedKey, CryptoModule.SymmetricAlgorithmOutputConverter);
			}

			string data2 = new SymmetricKeyCryptoModule(alg).Decrypt<string>(cipher, CryptoModule.StringOutputConverter);
			Assert.AreEqual<string>(data1, data2);
		}

		#endregion

		#region Test: public void DecryptSecret03()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void DecryptSecret03()
		{
			string data1 = "lkjasdlf lskejr lk4j5l k6j lk6j lj lk6j lkj lj l3j lkj lkj lkej lkjlkjlkjlkj";
			string pwd = "lkjlaksjdtlkjlaksjdlkf";
			using (eWalletDataSet ds = new eWalletDataSet())
			{
				var key = ds.Groups.AddGroupsRow("Default", null, new PasswordCryptoModule(pwd));
				var secret = ds.Secrets.AddSecretsRow(null, data1, key, new PasswordCryptoModule(pwd));
				string data2 = secret.DecryptString(new PasswordCryptoModule(pwd));

				Assert.AreEqual<string>(data1, data2);
			}
		}

		#endregion

		#region Test: public void DecryptSecret04()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void DecryptSecret04()
		{
			string data1 = "lkjasdlf lskejr lk4j5l k6j lk6j lj lk6j lkj lj l3j lkj lkj lkej lkjlkjlkjlkj";
			X509Certificate2 cert = new X509Certificate2(Properties.Resources.eWalletTestCertificate1);
			using (eWalletDataSet ds = new eWalletDataSet())
			{
				var key = ds.Groups.AddGroupsRow("Default", null, new CertificationCryptoModule(cert));
				var secret = ds.Secrets.AddSecretsRow(null, data1, key, new CertificationCryptoModule(cert));
				string data2 = secret.DecryptString(new CertificationCryptoModule(cert));

				Assert.AreEqual<string>(data1, data2);
			}
		}

		#endregion

		#region Test: public void DecryptSecret05()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void DecryptSecret05()
		{
			byte[] data1 = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
			string pwd = "lkjlaksjdtlkjlaksjdlkf";
			
			using (eWalletDataSet ds = new eWalletDataSet())
			{
				var key = ds.Groups.AddGroupsRow("Default", null, new PasswordCryptoModule(pwd));
				var secret = ds.Secrets.AddSecretsRow(null, data1, key, new PasswordCryptoModule(pwd));
				byte[] data2 = secret.DecryptData(new PasswordCryptoModule(pwd));

				CollectionAssert.AreEqual(data1, data2);
			}
		}

		#endregion

		#region Test: public void DecryptSecret06()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void DecryptSecret06()
		{
			byte[] data1 = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
			X509Certificate2 cert = new X509Certificate2(Properties.Resources.eWalletTestCertificate1);
			using (eWalletDataSet ds = new eWalletDataSet())
			{
				var key = ds.Groups.AddGroupsRow("Default", null, new CertificationCryptoModule(cert));
				var secret = ds.Secrets.AddSecretsRow(null, data1, key, new CertificationCryptoModule(cert));
				byte[] data2 = secret.DecryptData(new CertificationCryptoModule(cert));

				CollectionAssert.AreEqual(data1, data2);
			}
		}

		#endregion
		


		#region Test: public void EncryptSecret01()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void EncryptSecret01()
		{
			string pwd = "p4$$w0rd";

			using (eWalletDataSet ds = new eWalletDataSet())
			{
				var key = ds.Groups.AddGroupsRow("Default", null, new PasswordCryptoModule(pwd));
				var secret = ds.Secrets.AddSecretsRow(null, "MyownPassword", key, new PasswordCryptoModule(pwd));

				Assert.IsNotNull(secret);
				Assert.AreEqual<Guid>(key.Id, secret.GroupId);
				Assert.IsTrue(secret.IsDescriptionNull());
				Assert.AreEqual<string>(MediaTypeNames.Text.Plain, secret.ContentType);
				Assert.IsTrue(secret.IsFileNameNull());
				Assert.IsNotNull(secret.GroupsRow);
				Assert.AreSame(key, secret.GroupsRow);
				Assert.IsNotNull(secret.EncryptedSecret);
				Assert.AreNotEqual<int>(0, secret.EncryptedSecret.Length);
			}
		}

		#endregion

		#region Test: public void EncryptSecret02()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void EncryptSecret02()
		{
			X509Certificate2 cert = new X509Certificate2(Properties.Resources.eWalletTestCertificate2);

			using (eWalletDataSet ds = new eWalletDataSet())
			{
				var key = ds.Groups.AddGroupsRow("Default", null, new CertificationCryptoModule(cert));
				var secret = ds.Secrets.AddSecretsRow(null, "MyownPassword", key, new CertificationCryptoModule(cert));

				Assert.IsNotNull(secret);
				Assert.AreEqual<Guid>(key.Id, secret.GroupId);
				Assert.IsTrue(secret.IsDescriptionNull());
				Assert.AreEqual<string>(MediaTypeNames.Text.Plain, secret.ContentType);
				Assert.IsTrue(secret.IsFileNameNull());
				Assert.IsNotNull(secret.GroupsRow);
				Assert.AreSame(key, secret.GroupsRow);
				Assert.IsNotNull(secret.EncryptedSecret);
				Assert.AreNotEqual<int>(0, secret.EncryptedSecret.Length);
			}
		}

		#endregion



		#region Test: public void SelectSecrets01()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void SelectSecrets01()
		{
			using (eWalletDataSet ds = new eWalletDataSet())
			{
				ds.Blobs.AddBlobsRow(Guid.NewGuid(), new byte[1]);

				ds.Groups.AddGroupsRow(Guid.NewGuid(), DateTime.UtcNow, "Admin", "Default", null, EncryptionMethod.Password, ds.Blobs[0], null);

				ds.Secrets.AddSecretsRow(Guid.NewGuid(), DateTime.UtcNow, "Admin", ds.Groups[0], "Secret 1", "text/plain", "inline", ds.Blobs[0]);
				ds.Secrets.AddSecretsRow(Guid.NewGuid(), DateTime.UtcNow, "Admin", ds.Groups[0], "Secret 2", "text/plain", "inline", ds.Blobs[0]);
				ds.Secrets.AddSecretsRow(Guid.NewGuid(), DateTime.UtcNow, "Admin", ds.Groups[0], "Secret 3", "text/plain", "inline", ds.Blobs[0]);

				ds.Tags.AddTagsRow("Tag 1");
				ds.Tags.AddTagsRow("Tag 2");
				ds.Tags.AddTagsRow("Tag 3");

				ds.SecretsTags.AddSecretsTagsRow(ds.Secrets[0], ds.Tags[0]); // Secret 1, Tag 1
				ds.SecretsTags.AddSecretsTagsRow(ds.Secrets[0], ds.Tags[1]); // Secret 1, Tag 2
				ds.SecretsTags.AddSecretsTagsRow(ds.Secrets[1], ds.Tags[0]); // Secret 2, Tag 1
				ds.SecretsTags.AddSecretsTagsRow(ds.Secrets[1], ds.Tags[1]); // Secret 2, Tag 2
				ds.SecretsTags.AddSecretsTagsRow(ds.Secrets[2], ds.Tags[2]); // Secret 3, Tag 3

				var tags = ds.Tags.Select(new EventfulList<string>("Tag 1", "Tag 2"));
				var secrets = ds.Secrets.Select(tags);

				Assert.IsNotNull(secrets);
				Assert.AreEqual<int>(2, secrets.Count());
				Assert.IsNotNull(secrets.FirstOrDefault(s => s.Description == "Secret 1"));
				Assert.IsNotNull(secrets.FirstOrDefault(s => s.Description == "Secret 2"));
				Assert.IsNull(secrets.FirstOrDefault(s => s.Description == "Secret 3"));
			}
		}

		#endregion

		#region Test: public void SelectSecrets02()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void SelectSecrets02()
		{
			using (eWalletDataSet ds = new eWalletDataSet())
			{
				ds.Blobs.AddBlobsRow(Guid.NewGuid(), new byte[1]);

				ds.Groups.AddGroupsRow(Guid.NewGuid(), DateTime.UtcNow, "Admin", "Default", null, EncryptionMethod.Certificate, ds.Blobs[0], null);

				ds.Secrets.AddSecretsRow("Secret 1", ds.Groups[0], ds.Blobs[0]);
				ds.Secrets.AddSecretsRow("Secret 2", ds.Groups[0], ds.Blobs[0]);
				ds.Secrets.AddSecretsRow("Secret 3", ds.Groups[0], ds.Blobs[0]);

				ds.Tags.AddTagsRow("Tag 1");
				ds.Tags.AddTagsRow("Tag 2");
				ds.Tags.AddTagsRow("Tag 3");

				ds.SecretsTags.AddSecretsTagsRow(ds.Secrets[0], ds.Tags[0]);

				ds.SecretsTags.AddSecretsTagsRow(ds.Secrets[1], ds.Tags[0]);
				ds.SecretsTags.AddSecretsTagsRow(ds.Secrets[1], ds.Tags[1]);

				ds.SecretsTags.AddSecretsTagsRow(ds.Secrets[2], ds.Tags[0]);
				ds.SecretsTags.AddSecretsTagsRow(ds.Secrets[2], ds.Tags[1]);
				ds.SecretsTags.AddSecretsTagsRow(ds.Secrets[2], ds.Tags[2]);

				var r1 = ds.Secrets.Select(ds.Tags.Select(new EventfulList<string>(" Tag 1")));
				Assert.AreEqual<int>(3, r1.Count());

				var r2 = ds.Secrets.Select(ds.Tags.Select(new EventfulList<string>(" Tag 1", "Tag 2")));
				Assert.AreEqual<int>(2, r2.Count());

				var r3 = ds.Secrets.Select(ds.Tags.Select(new EventfulList<string>("Tag 3", " Tag 1", "Tag 2")));
				Assert.AreEqual<int>(1, r3.Count());
			}
		}

		#endregion
		


		#region Test: public void SelectSecretsTags01()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void SelectSecretsTags01()
		{
			using (eWalletDataSet ds = new eWalletDataSet())
			{
				ds.Blobs.AddBlobsRow(Guid.NewGuid(), new byte[1]);

				ds.Groups.AddGroupsRow(Guid.NewGuid(), DateTime.UtcNow, "Admin", "Default", null, EncryptionMethod.Password, ds.Blobs[0], null);

				ds.Secrets.AddSecretsRow(Guid.NewGuid(), DateTime.UtcNow, "Admin", ds.Groups[0], "Secret 1", "text/plain", "inline", ds.Blobs[0]);
				ds.Secrets.AddSecretsRow(Guid.NewGuid(), DateTime.UtcNow, "Admin", ds.Groups[0], "Secret 2", "text/plain", "inline", ds.Blobs[0]);
				ds.Secrets.AddSecretsRow(Guid.NewGuid(), DateTime.UtcNow, "Admin", ds.Groups[0], "Secret 3", "text/plain", "inline", ds.Blobs[0]);

				ds.Tags.AddTagsRow("Tag 1");
				ds.Tags.AddTagsRow("Tag 2");
				ds.Tags.AddTagsRow("Tag 3");

				ds.SecretsTags.AddSecretsTagsRow(ds.Secrets[0], ds.Tags[0]);
				ds.SecretsTags.AddSecretsTagsRow(ds.Secrets[1], ds.Tags[1]);
				ds.SecretsTags.AddSecretsTagsRow(ds.Secrets[2], ds.Tags[2]);

				var r1 = ds.SecretsTags.Select(new eWalletDataSet.SecretsRow[] { ds.Secrets[0] });
				Assert.AreEqual<int>(1, r1.Count());

				var r2 = ds.SecretsTags.Select(new eWalletDataSet.TagsRow[] { ds.Tags[1], ds.Tags[2] });
				Assert.AreEqual<int>(2, r2.Count());
			}

		}

		#endregion
		


		#region Test: public void SelectTags01()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void SelectTags01()
		{
			using (eWalletDataSet ds = new eWalletDataSet())
			{
				ds.Tags.AddTagsRow("Tag 1");
				ds.Tags.AddTagsRow("Tag 2");
				ds.Tags.AddTagsRow("Tag 3");

				var tags = new List<eWalletDataSet.TagsRow>(ds.Tags.Select(new string[] { "Tag 1", "Tag 3" }));
				Assert.AreEqual<int>(2, tags.Count);
				Assert.IsNotNull(tags.First(t => t.Label == "Tag 1"));
				Assert.IsNotNull(tags.First(t => t.Label == "Tag 3"));
				Assert.IsNull(tags.FirstOrDefault(t => t.Label == "Tag 2"));
			}
		}

		#endregion

		#region Test: public void SelectTags02()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void SelectTags02()
		{
			using (eWalletDataSet ds = new eWalletDataSet())
			{
				string[] arr = null;
				var tags = new List<eWalletDataSet.TagsRow>(ds.Tags.Select(arr));
				Assert.IsNotNull(tags);
				Assert.AreEqual<int>(0, tags.Count);
			}
		}

		#endregion

		#region Test: public void SelectTags03()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void SelectTags03()
		{
			using (eWalletDataSet ds = new eWalletDataSet())
			{
				ds.Tags.AddTagsRow(new Guid("{2C1FB976-CF01-42b8-82FB-DE712079C843}"), "Tag 1");
				ds.Tags.AddTagsRow(new Guid("{2C1FB976-CF01-42b8-82FB-DE712079C842}"), "Tag 2");
				ds.Tags.AddTagsRow(new Guid("{2C1FB976-CF01-42b8-82FB-DE712079C841}"), "Tag 3");

				string[] arr = null;
				var tags = from t in ds.Tags.Select(arr) orderby t.Label select t;
				List<eWalletDataSet.TagsRow> list = new List<eWalletDataSet.TagsRow>(tags);

				Assert.AreEqual<int>(3, list.Count);
				Assert.AreEqual<string>("Tag 1", list[0].Label);
				Assert.AreEqual<string>("Tag 2", list[1].Label);
				Assert.AreEqual<string>("Tag 3", list[2].Label);
			}
		}

		#endregion

		#region Test: public void SelectTags04()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void SelectTags04()
		{
			using (eWalletDataSet ds = new eWalletDataSet())
			{
				ds.Tags.AddTagsRow("Tag 3");
				ds.Tags.AddTagsRow("Tag 2");
				ds.Tags.AddTagsRow("Tag 1");

				var tags = from t in ds.Tags where t.Label == "Tag 2" || t.Label == "Tag 3" orderby t.Label select t;
				List<eWalletDataSet.TagsRow> list = new List<eWalletDataSet.TagsRow>(tags);

				Assert.AreEqual<int>(2, list.Count);
				Assert.AreEqual<string>("Tag 2", list[0].Label);
				Assert.AreEqual<string>("Tag 3", list[1].Label);
			}
		}

		#endregion

		#region Test: public void SelectTags05()

		[global::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()]
		[global::Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute(" ")]
		public void SelectTags05()
		{
			using (eWalletDataSet ds = new eWalletDataSet())
			{
				ds.Tags.AddTagsRow("Tag 1");
				ds.Tags.AddTagsRow("Tag 2");
				ds.Tags.AddTagsRow("Tag 3");

				var r1 = ds.Tags.Select(new EventfulList<string>("Tag 2"));
				Assert.AreEqual<int>(1, r1.Count());
				Assert.IsNotNull(r1.First(t => t.Label == "Tag 2"));

				var r2 = ds.Tags.Select(new EventfulList<string>("Tag 1", "Tag 3"));
				Assert.AreEqual<int>(2, r2.Count());
				Assert.IsNotNull(r2.First(t => t.Label == "Tag 1"));
				Assert.IsNotNull(r2.First(t => t.Label == "Tag 3"));

				var r3 = ds.Tags.Select(new EventfulList<string>("Tag 1", "Tag 3", "Tag 2"));
				Assert.AreEqual<int>(3, r3.Count());
				Assert.IsNotNull(r3.First(t => t.Label == "Tag 1"));
				Assert.IsNotNull(r3.First(t => t.Label == "Tag 2"));
				Assert.IsNotNull(r3.First(t => t.Label == "Tag 3"));
			}
		}

		#endregion
		
	}
}
